package com.ldk.base.framework.service.impl;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.ldk.base.framework.dao.IBaseDAO;
import com.ldk.base.framework.service.IBaseService;

/**
 * BaseService Service 基类
 * @author xiangwl
 *
 * @param <T>
 */
public abstract class BaseService<T extends Serializable> implements IBaseService<T> {
	private Class<?> clazz;
	
	protected BaseService(){
		clazz = this.getClass();
	}
	
	/**
	 * 获取DAO的方法
	 * @return
	 */
	protected abstract IBaseDAO<T> getBaseDao();
	/**
	 * 默认日志
	 */
	protected Logger logger = getLogger();
	
	/**
	 * 获取Logger
	 * @return
	 */
	public Logger getLogger()
	{
		if(clazz != null)
			return LoggerFactory.getLogger(clazz);
		else{
			return LoggerFactory.getLogger("PROJECT");
		}
	}
	
	/**
	 * 获取ID最大值
	 * @return
	 */
	@Override
	public Object getMaxId(String dbKey) 
	{
		
		IBaseDAO<T> baseDao = getBaseDao();
		if(baseDao != null)
		{
			try{
				return baseDao.getMaxId(dbKey);
			}
			catch(Exception e)
			{
				logger.error(e.getMessage());
			}
		}
		return null;
	}
	
	@Override
	public Boolean exist(String dbKey, T query){
		IBaseDAO<T> baseDao = getBaseDao();
		if(baseDao != null)
		{
			try{
				return baseDao.exist(dbKey, query);
			}
			catch(Exception e)
			{
				logger.error(e.getMessage());
			}
		}
		return false;
	}
	
	@Override
	public <V extends T> V selectOne(String dbKey, T query){
		IBaseDAO<T> baseDao = getBaseDao();
		if(baseDao != null)
		{
			try{
				return baseDao.selectOne(dbKey, query);
			}
			catch(Exception e)
			{
				logger.error(e.getMessage());
			}
		}
			
		return null;
	}
	
	@Override
	public <V extends T> V selectOne(String dbKey, Map<String, Object> query){
		IBaseDAO<T> baseDao = getBaseDao();
		if(baseDao != null)
		{
			try{
				return baseDao.selectOne(dbKey, query);
			}
			catch(Exception e)
			{
				logger.error(e.getMessage());
			}
		}
			
		return null;
	}
	
	
	@Override
	public <V extends T> V selectOne(String dbKey, T query, Sort sort){
		IBaseDAO<T> baseDao = getBaseDao();
		if(baseDao != null)
		{
			try{
				return baseDao.selectOne(dbKey, query, sort);
			}
			catch(Exception e)
			{
				logger.error(e.getMessage());
			}
		}
			
		return null;
	}
   

	@Override
	public <V extends T> V selectByKey(String dbKey, T query){
		IBaseDAO<T> baseDao = getBaseDao();
		if(baseDao != null)
		{
			try{
				return baseDao.selectByKey(dbKey, query);
			}
			catch(Exception e)
			{
				logger.error(e.getMessage());
			}
		}

		return null;
	}

	@Override
	public <V extends T> List<V> selectList(String dbKey, T query){
		IBaseDAO<T> baseDao = getBaseDao();
		if(baseDao != null)
		{
			try{
				return baseDao.selectList(dbKey, query);
			}
			catch(Exception e)
			{
				logger.error(e.getMessage());
			}
		}
		
		return null;
	}

	@Override
	public <V extends T> List<V> selectListUpper(String dbKey, T query){
		IBaseDAO<T> baseDao = getBaseDao();
		if(baseDao != null)
		{
			try{
				return baseDao.selectListUpper(dbKey, query);
			}
			catch(Exception e)
			{
				logger.error(e.getMessage());
			}
		}
		return null;
	}


	@Override
	public <V extends T> List<V> selectList(String dbKey, T query, Sort sort){
		IBaseDAO<T> baseDao = getBaseDao();
		if(baseDao != null)
		{
			try{
				return baseDao.selectList(dbKey, query, sort);
			}
			catch(Exception e)
			{
				logger.error(e.getMessage());
			}
		}
		
		return null;
	}

	@Override
	public <V extends T> List<V> selectAll(String dbKey){
		IBaseDAO<T> baseDao = getBaseDao();
		if(baseDao != null)
		{
			try{
				return baseDao.selectAll(dbKey);
			}
			catch(Exception e)
			{
				logger.error(e.getMessage());
			}
		}
	
		return null;
	}

	@Override
	public <V extends T> List<V> selectList(String dbKey, T query, Pageable pageable){
		IBaseDAO<T> baseDao = getBaseDao();
		if(baseDao != null)
		{
			try
			{
				return baseDao.selectList(dbKey, query, pageable);
			}
			catch(Exception e)
			{
				logger.error(e.getMessage());
			}
		}
			
		return null;
	}

	@Override
	public <V extends T> Page<V> selectPageList(String dbKey, T query, Pageable pageable){
		IBaseDAO<T> baseDao = getBaseDao();
		if(baseDao != null)
		{
			try{
				return baseDao.selectPageList(dbKey, query, pageable);
			}
			catch(Exception e)
			{
				logger.error(e.getMessage());
			}
		}
			
		return null;
	}
	
	
	@Override
	public <K, V> Map<K, V> selectMap(String dbKey, T query, String mapKey){
		IBaseDAO<T> baseDao = getBaseDao();
		if(baseDao != null)
		{
			try{
				return baseDao.selectMap(dbKey, query, mapKey);
			}
			catch(Exception e)
			{
				logger.error(e.getMessage());
			}
		}
			
		return null;
	}
	
	@Override
	public <K, V> Map<K, V> selectMap(String dbKey, T query,String mapKey, Sort sort)
	{
		IBaseDAO<T> baseDao = getBaseDao();
		if(baseDao != null)
		{
			try{
				return baseDao.selectMap(dbKey, query, mapKey, sort);
			}
			catch(Exception e)
			{
				logger.error(e.getMessage());
			}
		}
			
		return null;
	}
	
	@Override
	public <K, V> Map<K, V> selectMap(String dbKey, T query, Pageable pageable, String mapKey){
		IBaseDAO<T> baseDao = getBaseDao();
		if(baseDao != null)
		{
			try{
				return baseDao.selectMap(dbKey, query, pageable, mapKey);
			}
			catch(Exception e)
			{
				logger.error(e.getMessage());
			}
		}
			
		return null;
	}

	@Override
	public Long selectCount(String dbKey){
		IBaseDAO<T> baseDao = getBaseDao();
		if(baseDao != null)
		{
			try{
				return baseDao.selectCount(dbKey);
			}
			catch(Exception e)
			{
				logger.error(e.getMessage());
			}
		}	
		return 0L;
	}

	@Override
	public Long selectCount(String dbKey, T query){
		IBaseDAO<T> baseDao = getBaseDao();
		if(baseDao != null)
		{
			try{
				return baseDao.selectCount(dbKey, query);
			}
			catch(Exception e)
			{
				logger.error(e.getMessage());
			}
		}	
		return 0L;
	}

	@Override
	public int insert(String dbKey, T entity){
		IBaseDAO<T> baseDao = getBaseDao();
		if(baseDao != null)
		{	
			return baseDao.insert(dbKey, entity);
		}
		return 0;
	}

	@Override
	public int insertUpper(String dbKey, T entity){
		IBaseDAO<T> baseDao = getBaseDao();
		if(baseDao != null)
		{
			return baseDao.insertUpper(dbKey, entity);
		}
		return 0;
	}


	@Override
	public long insertAndGetAutoIncrementId(String dbKey, T entity, String keyField){
		IBaseDAO<T> baseDao = getBaseDao();
		if(baseDao != null)
		{	
			return baseDao.insertAndGetAutoIncrementId(dbKey, entity, keyField);
		}
		return 0;
	}

	@Transactional(propagation=Propagation.REQUIRED,rollbackFor={Exception.class})
	@Override
	public int delete(String dbKey, T query){
		IBaseDAO<T> baseDao = getBaseDao();
		if(baseDao != null)
		{
			return baseDao.delete(dbKey, query);
		}
		return 0;
	}

	@Override
	public int deleteByKey(String dbKey, T query){
		IBaseDAO<T> baseDao = getBaseDao();
		if(baseDao != null)
		{
			return baseDao.deleteByKey(dbKey, query);
		}
		return 0;
	}

	@Transactional(propagation=Propagation.REQUIRED,rollbackFor={Exception.class})
	@Override
	public int deleteAll(String dbKey){
		IBaseDAO<T> baseDao = getBaseDao();
		if(baseDao != null)
		{
			return baseDao.deleteAll(dbKey);
		}
		return 0;
	}
	
	@Override
	public int updateByKey(String dbKey, T entity) {
		IBaseDAO<T> baseDao = getBaseDao();
		if(baseDao != null)
		{
			return baseDao.updateByKey(dbKey, entity);
		}
		return 0;
	}

	@Override
	public int updateUpperByKey(String dbKey, T entity) {
		IBaseDAO<T> baseDao = getBaseDao();
		if(baseDao != null)
		{
			return baseDao.updateUpperByKey(dbKey, entity);
		}
		return 0;
	}


	@Override
	public int update(String dbKey, T entity){
		IBaseDAO<T> baseDao = getBaseDao();
		if(baseDao != null)
		{
			return baseDao.update(dbKey, entity);
		}
		return 0;
	}

	@Override
	public long generateID(long n){
		double base = Math.pow(10, n-1);
		long id = (long) ((Math.random() * 9 + 1) * base);
		return id;
	}
}
